

import sys
import os
import numpy as np
import cv2
from ctypes import *
import ctypes

import time


class Cascade(Structure):
    _fields_ = [("w", c_int), ("h", c_int), ("stagelen", c_int),
                ("weaklen", c_int), ("weaklen", c_int), ("maxstagelen", c_int)]


out_dir = '.'
out_dir = os.path.dirname(os.path.realpath(__file__))
dll = CDLL('%s/libadaboost.dll' % out_dir)
dll.load_haar_cascade.argtypes = [c_char_p]
dll.load_haar_cascade.restype = POINTER(Cascade)

dll.detect_object.argtypes = [
    POINTER(Cascade),
    np.ctypeslib.ndpointer(dtype=np.uint8, ndim=2),
    c_int, c_int, c_int, c_int,
    c_double, c_double, c_double,
    c_int,
    c_double, c_int,
    # POINTER(c_int),
    np.ctypeslib.ndpointer(dtype=np.int, ndim=1),
    # c_int,
]
dll.detect_object.restype = c_int
dll.free_cascade.argtypes = [POINTER(Cascade)]


class HaarCascade(object):
    def __init__(self, fn=''):
        self.ca = None
        if len(fn) > 0:
            self.load(fn)

    def __del__(self):
        if self.ca is not None:
            dll.free_cascade(self.ca)

    def load(self, fn):
        aa = dll.load_haar_cascade(fn)
        if aa is None:
            return None

        self.ca = aa.contents
        return self.ca

    def detect(self, im, ssmin, ss=1.1, stepxy=1, mincnt=5):
        ca = self.ca
        if len(im.shape) > 2:
            gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
        else:
            gray = im
        h, w = gray.ctypes.shape
        step, cn = gray.ctypes.strides
        arrlen = 10000
        arr = np.zeros((arrlen), dtype=np.int)
    # int detect_object(CASCADE* ca, const uint8_t* data, int h, int w, int step, int cn, double ssmin, double ssmax, double ss, int stepxy, int* B, int B_len)
        #num = dll.detect_object(ca, gray, h, w, step, cn, c_double(ssmin), c_double(100), c_double(ss), c_int(stepxy), arr)
        num = dll.detect_object(ca, gray, h, w, step, cn,
                                c_double(ssmin), c_double(
                                    100), c_double(ss), c_int(stepxy),
                                c_double(0.8), c_int(mincnt), arr, c_int(arrlen))
        out = []
        for i in range(0, num*4, 4):
            r = (arr[i], arr[i+1], arr[i+2], arr[i+3])
            out.append(r)

        return out


def load_cascade(fn):
    ca = HaarCascade()
    ca1 = ca.load(fn)
    if ca1 is None:
        return None
    return ca


def detect(ca, im, ssmin, ss=1.1, stepxy=1, mincnt=5):
    return ca.detect(im, ssmin, ss, stepxy, mincnt)


def test_adaboost():
    os.chdir('D:/data/通力电梯七段管OCR/adaboost')
    model_path = '.'
    fn = '%s/cas.dat' % model_path
    fn = fn.encode(encoding='gb2312')
    ca = load_cascade(fn)
    if ca is None:
        print('load_cascade error')
        return 0

    os.chdir('D:/data/通力电梯七段管OCR/tonlipic/image_biaozhu_test')
    fnlist = ['0.jpg']
    fnlist = os.listdir('./')
    for fn in fnlist:
        if '.jpg' not in fn:
            continue

        im = cv2.imread(fn, 1)
        out = detect(ca, im, 1, 1.1, 1, 5)
        for r in out:
            cv2.rectangle(im, (r[0], r[1]), (r[2], r[3]), (0, 0, 255), 2)
        cv2.imshow('asdfasfd', im)
        cv2.waitKey(-1)


def test_adaboost2():
    os.chdir('D:/data/美的纸箱喷码/相机拍')
    model_path = '.'
    fn = '../adaboost/cas.dat'
    fn = fn.encode(encoding='gb2312')
    ca = load_cascade(fn)
    if ca is None:
        print('load_cascade error')
        return 0

    os.chdir('D:/data/美的纸箱喷码/相机拍')
    fnlist = ['0.jpg']
    fnlist = os.listdir('./')
    cv2.namedWindow('img', 0)
    for fn in fnlist:
        if '.jpg' not in fn:
            continue

        im = cv2.imread(fn, 1)
        out = detect(ca, im, 4, 1.1, 1, 10)
        for r in out:
            cv2.rectangle(im, (r[0], r[1]), (r[2], r[3]), (0, 0, 255), 2)
        cv2.imshow('img', im)
        cv2.waitKey(-1)


if __name__ == "__main__":
    test_adaboost2()
